home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 2 / AACD 2.iso / AACD / Online / Socks5 / src / server / flow.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-03-10  |  5.4 KB  |  178 lines

  1. /* Copyright (c) 1995-1999 NEC USA, Inc.  All rights reserved.               */
  2. /*                                                                           */
  3. /* The redistribution, use and modification in source or binary forms of     */
  4. /* this software is subject to the conditions set forth in the copyright     */
  5. /* document ("Copyright") included with this distribution.                   */
  6.  
  7. /*
  8.  * $Id: flow.c,v 1.31.4.4 1999/02/03 22:35:34 steve Exp $
  9.  */
  10.  
  11. /* This file has all the function to do tcp proxying itself.  The only one   */
  12. /* that is visible to the outside world should be HandleTcpConnection.       */
  13. #include "socks5p.h"
  14. #include "daemon.h"
  15. #include "proxy.h"
  16. #include "flow.h"
  17. #include "log.h"
  18. #include "msg.h"
  19.  
  20. #ifndef INACTIVITY_TIMEOUT
  21. #define INACTIVITY_TIMEOUT 15*60 /* How much inactivity will I tolerate???   */
  22. #endif
  23.  
  24. static int proxyinturn() {
  25.     static int turn = 0;
  26.  
  27.     return turn = turn?0:1;
  28. }
  29.  
  30. static int FlowSetup(S5Packet *buf) {
  31.     char *olddata = buf->data;
  32.  
  33.     if (buf->data == NULL) {
  34.     buf->data = malloc(GENERICBUFSIZE);
  35.     if (buf->data) S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "Flow Setup: Allocated Buffer");
  36.     buf->len  = GENERICBUFSIZE;
  37.     buf->off  = 0;
  38.     }
  39.  
  40.     if (buf->len == buf->off) {
  41.     buf->data = realloc(olddata = buf->data, buf->len += GENERICBUFSIZE);
  42.     if (buf->data) S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "Flow Setup: Grew Buffer");
  43.     }
  44.  
  45.     if (buf->data == NULL) {
  46.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_WARNING, 0, "Flow Setup: Couldn't allocate buffer space");
  47.     if (!olddata) free(olddata);
  48.     return -1;
  49.     }
  50.  
  51.     return 0;
  52. }
  53.  
  54. int S5TcpFlowRecv(S5IOInfo *iio, S5IOInfo *oio, S5Packet *packet, int *dir) {
  55.     S5IOHandle fdsbits = ((iio->fd > oio->fd)?iio->fd:oio->fd)+1;
  56.     fd_set fds, xfds, bu;
  57.     S5IOInfo *io;
  58.     char *string;
  59.     int n;
  60.     int turn = 1;
  61.  
  62.     FD_ZERO(&bu);
  63.     if (*dir & S5_DIRECTION_OUT) FD_SET(iio->fd, &bu);
  64.     if (*dir & S5_DIRECTION_IN)  FD_SET(oio->fd, &bu);
  65.  
  66.     if (FlowSetup(packet) < 0) {
  67.     return -1;
  68.     }
  69.  
  70.     for (fds = bu ; ; fds = bu) {
  71.     struct timeval tout;
  72.  
  73.     tout.tv_sec = idletimeout*60;
  74.     tout.tv_usec = 0;
  75.     if (!FD_ISSET(iio->fd,  &fds) && !FD_ISSET(oio->fd, &fds)) {
  76.         S5LogUpdate(S5LogDefaultHandle, S5_LOG_WARNING, 0, "Flow Recv: Neither file descriptor is set");
  77.         return -1;
  78.     }
  79.  
  80.         xfds = fds;
  81.     switch (select(fdsbits, &fds, NULL, &xfds, &tout)) {
  82.         case -1:
  83.         if (ISSOCKETERROR(EINTR)) continue;
  84.         S5LogUpdate(S5LogDefaultHandle, S5_LOG_WARNING, 0, "Flow Recv: Select failed: %m");
  85.         return -1;
  86.         case 0:
  87.         S5LogUpdate(S5LogDefaultHandle, S5_LOG_WARNING, 0, "Flow Recv: Select failed: Inactivity timeout");
  88.         return -1;
  89.     }
  90.  
  91.     if (FD_ISSET(iio->fd, &xfds) && FD_ISSET(oio->fd, &xfds))
  92.             turn = proxyinturn(); 
  93.         else if (FD_ISSET(iio->fd, &xfds))
  94.             turn = 1;
  95.         else if (FD_ISSET(oio->fd, &xfds))
  96.             turn = 0;
  97.         else if (FD_ISSET(iio->fd, &fds) && FD_ISSET(oio->fd, &fds))
  98.             turn = proxyinturn();
  99.         else if (FD_ISSET(iio->fd, &fds))
  100.             turn = 1;
  101.     else if (FD_ISSET(oio->fd, &fds))
  102.             turn = 0;
  103.     else {
  104.         S5LogUpdate(S5LogDefaultHandle, S5_LOG_WARNING, 0, "Flow Recv: Invalid file descriptor set");
  105.         return -1;
  106.     }
  107.  
  108.         if (turn) {
  109.             *dir = S5_DIRECTION_OUT;
  110.             string = "client";
  111.             io = iio;
  112.         } else {
  113.             *dir = S5_DIRECTION_IN;
  114.             string = "server";
  115.             io = oio;
  116.         }
  117.  
  118.         packet->oob = 0;
  119.         if (FD_ISSET(io->fd, &xfds))
  120.             (void) ioctl(io->fd, SIOCATMARK, (char *)&packet->oob);
  121.  
  122. #define RECV_IOFLAGS S5_IOFLAGS_TIMED|S5_IOFLAGS_RESTART
  123.  
  124.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "Flow Recv: Reading from %s socket", string);
  125.     switch ((n = S5BufReadPacket(io->fd, io, packet->data + packet->off, packet->oob?1:packet->len - packet->off, 0))) {
  126.         case -1: 
  127.         S5LogUpdate(S5LogDefaultHandle, S5_LOG_WARNING,  0, "Flow Recv: %s Read failed: %m", string);
  128.         return -1;
  129.         case 0:
  130.         S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(0), 0, "Flow Recv: %s closed connection", string);
  131.         return 0;
  132.         default:
  133.         S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "Flow Recv: Read %d bytes from %s socket", n, string);
  134.         packet->off += n;
  135.         return n;
  136.     }
  137.     }
  138. }
  139.  
  140. int S5TcpFlowSend(S5IOInfo *iio, S5IOInfo *oio, S5Packet *packet, int *dir) {
  141.     double timerm = (double)idletimeout*60;
  142.     S5IOInfo *io;
  143.     char *string;
  144.     int n;
  145.  
  146.     switch (*dir) {
  147.     case S5_DIRECTION_OUT:
  148.         string = "server";
  149.         io = oio;
  150.         break;
  151.     case S5_DIRECTION_IN:
  152.         string = "client";
  153.         io = iio;
  154.         break;
  155.     default:
  156.         S5LogUpdate(S5LogDefaultHandle, S5_LOG_WARNING, 0, "Flow Send: Invalid direction: %d", *dir);
  157.         return -1;
  158.     }
  159.  
  160.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "Flow Send: Writing %d bytes to %s socket", packet->off, string);    
  161.  
  162. #define SEND_IOFLAGS S5_IOFLAGS_TIMED|S5_IOFLAGS_RESTART|S5_IOFLAGS_NBYTES
  163.  
  164.     switch ((n = S5IOSend(io->fd, io, packet->data, packet->off, packet->oob?MSG_OOB:0, SEND_IOFLAGS, &timerm))) {
  165.     case -1: 
  166.         S5LogUpdate(S5LogDefaultHandle, S5_LOG_WARNING, 0, "Flow Send: %s Write failed: %m", string);
  167.         return -1;
  168.     case 0:
  169.         S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(0), 0, "Flow Send: %s closed connection", string);
  170.         return 0;
  171.     default:
  172.         S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "Flow Send: Wrote %d bytes to %s", n, string);
  173.         packet->off -= n;
  174.         return n;
  175.     }
  176. }
  177.  
  178.